﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace CHS.ChengDu.Service
{
    public static class CHSEncryption
    {
        /// <summary>
        /// 签名
        /// </summary>
        /// <param name="_input"></param>
        /// <returns></returns>
        public static CHSEncryptionOutput gm_sign_key(CHSEncryptionInput _input)
        {
           

            if (string.IsNullOrEmpty(_input.PublicKey))
            {
                return new CHSEncryptionOutput
                {
                    Code = -1,
                    Message = "明文不能为空"
                };
            }

            if (string.IsNullOrEmpty(_input.PrivateKey))
            {
                return new CHSEncryptionOutput
                {
                    Code = -1,
                    Message = "明文不能为空"
                };
            }

            if (string.IsNullOrEmpty(_input.Input))
            {
                return new CHSEncryptionOutput
                {
                    Code = -1,
                    Message = "[input]明文不能为空"
                };
            }

            int code = 0;

            string userId = string.IsNullOrEmpty(_input.UserId) ? "" : _input.UserId;
            byte[] pub_key = Encoding.UTF8.GetBytes(_input.PublicKey);
            byte[] prv_key = Encoding.UTF8.GetBytes(_input.PrivateKey);
            byte[] userid = Encoding.UTF8.GetBytes(userId);
            byte[] msg = Encoding.UTF8.GetBytes(_input.Input);
            byte[] singrs = new byte[1024];
            code = gm_sign_key(userid, prv_key, pub_key, msg, msg.Length, singrs);
            var output = Encoding.UTF8.GetString(singrs).Replace("\u0000", "").Trim();
            return new CHSEncryptionOutput()
            {
                Code = code,
                Message = code > 0 ? "成功" : "失败",
                output = output,
            };
        }
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="data"></param>
        /// <param name="publicKey"></param>
        /// <returns></returns>
        public static CHSEncryptionOutput gm_ecb_encrypt_key(CHSEncryptionInput _input)
        {
            if (string.IsNullOrEmpty(_input.PublicKey))
            {
                return new CHSEncryptionOutput
                {
                    Code = -1,
                    Message = "[PublicKey]公钥不能为空"
                };
            }

            if (string.IsNullOrEmpty(_input.Input))
            {
                return new CHSEncryptionOutput
                {
                    Code = -1,
                    Message = "[input]明文不能为空"
                };
            }

            byte[] plain = Encoding.UTF8.GetBytes(_input.Input);
            byte[] cipher = new byte[(plain.Length + 2048)];
            byte[] pub_key = Encoding.UTF8.GetBytes(_input.PublicKey);
            int code = gm_ecb_encrypt_key(pub_key, plain, plain.Length, cipher);
            string output = Encoding.UTF8.GetString(cipher).Replace("\u0000", "").Trim();
            return new CHSEncryptionOutput()
            {
                Code = code,
                output = output,
                Message = code>0?"成功":"失败"
            };

        }
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="data"></param>
        /// <param name="publicKey"></param>
        /// <returns></returns>
        public static CHSEncryptionOutput gm_ecb_decrypt_key(CHSEncryptionInput _input)
        {
            if (string.IsNullOrEmpty(_input.PublicKey))
            {
                return new CHSEncryptionOutput
                {
                    Code = -1,
                    Message = "[PublicKey]公钥不能为空"
                };
            }

            if (string.IsNullOrEmpty(_input.Input))
            {
                return new CHSEncryptionOutput
                {
                    Code = -1,
                    Message = "[input]明文不能为空"
                };
            }

            byte[] pub_key = Encoding.UTF8.GetBytes(_input.PublicKey);
            byte[] cipher = Encoding.UTF8.GetBytes(_input.Input);
            byte[] plain = new byte[(cipher.Length + 2048)];
            var code = gm_ecb_decrypt_key(pub_key, cipher, cipher.Length, plain);
            var output = Encoding.UTF8.GetString(plain).Replace("\u0000", "").Trim();
            return new CHSEncryptionOutput()
            {
                Code = code,
                output = output,
                Message = code > 0 ? "成功" : "失败"
            };
        }

        [DllImport("hsafsiyhsafe.dll", CharSet = CharSet.Ansi, EntryPoint = "gm_ecb_encrypt_key@16", CallingConvention = CallingConvention.StdCall)]
        private static extern int gm_ecb_encrypt_key(byte[] pub_key, byte[] plain, int plain_len, byte[] cipher);

        [DllImport("hsafsiyhsafe.dll", CharSet = CharSet.Ansi, EntryPoint = "gm_ecb_decrypt_key@16", CallingConvention = CallingConvention.StdCall)]
        private static extern int gm_ecb_decrypt_key(byte[] pub_key, byte[] cipher, int cipher_len, byte[] plain);

        [DllImport("hsafsitool.dll", CharSet = CharSet.Ansi, EntryPoint = "gm_keygen@8", CallingConvention = CallingConvention.StdCall)]
        private static extern int gm_keygen(byte[] pub_key, byte[] prv_key);

        [DllImport("hsafsitool.dll", CharSet = CharSet.Ansi, EntryPoint = "gm_sign_key@24", CallingConvention = CallingConvention.StdCall)]
        private static extern int gm_sign_key(byte[] userid, byte[] prv_key, byte[] pub_key, byte[] msg, int msg_len, byte[] singrs);

        [DllImport("hsafsitool.dll", CharSet = CharSet.Ansi, EntryPoint = "gm_verify_key@20", CallingConvention = CallingConvention.StdCall)]
        private static extern int gm_verify_key(byte[] userid, byte[] prv_key, byte[] pub_key, byte[] msg, int msg_len, byte[] singrs);
    }
}
